package com.mgee.netty.server.netty;

import java.util.List;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.CorruptedFrameException;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class CustomProtobufInt32FrameDecoder extends ByteToMessageDecoder {

	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
		// TODO Auto-generated method stub
		
//		  log.info("raw message length is " + in.readableBytes());
//		  
//		  byte[] bytes=new byte[in.readableBytes()];//
//		  in.getBytes(in.readerIndex(),bytes);
//		  
//		  String binStr = ""; for(byte data : bytes) { binStr += toBinary(data)+","; }
//		  log.info("message binary bytes is: " + binStr);
//		  
//		  String str=new String(bytes); log.info("message string is " + str);
		 

		in.markReaderIndex();
		int preIndex = in.readerIndex();
		// log.info("preIndex is " + preIndex);
		int length = readRawInt32(in);
		// int length = in.readInt();
		// log.info("in.readerIndex() is " + in.readerIndex());
		//log.info("header length is " + length);
		if (preIndex == in.readerIndex()) {
			return;
		}
		if (length < 0) {
			throw new CorruptedFrameException("negative length: " + length);
		}

		if (in.readableBytes() < length) {
			in.resetReaderIndex();
		} else {
			out.add(in.readRetainedSlice(length));
		}
	}

	private static int readRawInt32(ByteBuf buffer) {
		if (!buffer.isReadable()) {
			return 0;
		}
		// buffer.markReaderIndex();
		byte tmp1 = buffer.readByte();
		byte tmp2 = buffer.readByte();
		byte tmp3 = buffer.readByte();
		byte tmp4 = buffer.readByte();
		int result = getIntFromBytes(tmp4, tmp3, tmp2, tmp1);
		return result;
	}

	private static int getIntFromBytes(byte high_h, byte high_l, byte low_h, byte low_l) {
		return (high_h & 0xff) << 24 | (high_l & 0xff) << 16 | (low_h & 0xff) << 8 | low_l & 0xff;
	}

	
//	  private static String toBinary(byte b) { StringBuffer sb = new
//	  StringBuffer();
//	  
//	  for(int i = 0; i < 8; ++i) { sb.append((b & (1 << i)) > 0 ? 1 : 0); } return
//	  sb.toString(); }
	 

}
